#include <iostream>
#include <fstream>
#include <string>
#include "CWishMgr.h"
#include "pb_cfg_act.pb.h"
#include "../mainctrl.h"

int CWishMgr::DoReq(MsgReqWish &stReq, MsgAnsWish & stAns)
{
    int iRet = 0;

    int iReqType = stReq.req_type();
    unsigned int iGid = stReq.gid();

    switch( iReqType )
    {
    case ECONST_WISH_REQ_INFO:
        iRet = this->GetWishInfo(iGid, stAns);
        break;
    case ECONST_WISH_REQ_SILVER:
    case ECONST_WISH_REQ_GOLD1:
    case ECONST_WISH_REQ_GOLD2:
        iRet = this->UserReqWish(iGid, iReqType, stAns);
        break;
    default:
        break;
    }

    return iRet;
}

int CWishMgr::UserReqWish(unsigned int uiGid, int iReqType, MsgAnsWish& stAns)
{
    int iRet = 0;

    //在cmdact里面已经做了用户数据存在的检查，这里直接用
    int iIndex = CMainCtrl::m_pstMain->m_stPlayerBaseInfoHash.HashFind(uiGid);
    CPlayerBaseInfo& stPlayerBaseInfo = CMainCtrl::m_pstMain->m_stPlayerBaseInfoHash[iIndex];

    //个人详细数据
    iIndex = CMainCtrl::m_pstMain->m_stPlayerDetailInfoHash.HashFind(uiGid);
    CPlayerDetailInfo& stPlayerDetailInfo = CMainCtrl::m_pstMain->m_stPlayerDetailInfoHash[iIndex];
    CWishData& stWishData = stPlayerDetailInfo._stWishData;

    //检查是否许愿过
    if( !this->CheckValidWish(iReqType, stWishData) )
    {
        return ERROR_WISH_INVALID;
    }
    this->UpdateData(uiGid);

    int iRatioTimes;
    iRet = this->_stWishCfg.GetWishRandomRatio(iReqType, iRatioTimes);
    CHECK_RETURN(iRet);

    switch(iReqType)
    {
    case ECONST_WISH_REQ_SILVER  :  //银币许愿
        {
            //检查钱币是否足够
            if( stPlayerBaseInfo._i64Silver<CONST_WISH_PAY_SILVER )
            {
                return ERROR_WISH_NOT_ENOUGH_MONEY;
            }
            //扣钱
            iRet = stPlayerBaseInfo.SubSilver(stPlayerBaseInfo._i64Silver, CONST_WISH_PAY_SILVER);
            CHECK_RETURN(iRet);
        }
        break;
    case ECONST_WISH_REQ_GOLD1   :  //10金币许愿
        {
            //是否vip用户
            if( stPlayerBaseInfo._chVipLevel<1 )
            {
                return ERROR_WISH_GOLD_NEED_VIP;
            }

            //检查钱币是否足够
            if( stPlayerBaseInfo._iGold<CONST_WISH_PAY_GOLD10 )
            {
                return ERROR_WISH_NOT_ENOUGH_MONEY;
            }
            //扣钱
            iRet = CMainCtrl::m_pstMain->m_stItemMgr.SubGold(uiGid, OSS_MONEY_MODULE_35, stPlayerBaseInfo._iGold, CONST_WISH_PAY_GOLD10);
            CHECK_RETURN(iRet);
        }
        break;
    case ECONST_WISH_REQ_GOLD2   :  //50金币许愿
        {
            //是否vip用户
            if( stPlayerBaseInfo._chVipLevel<1 )
            {
                return ERROR_WISH_GOLD_NEED_VIP;
            }

            //检查钱币是否足够
            if( stPlayerBaseInfo._iGold<CONST_WISH_PAY_GOLD50 )
            {
                return ERROR_WISH_NOT_ENOUGH_MONEY;
            }
            //扣钱
            iRet = CMainCtrl::m_pstMain->m_stItemMgr.SubGold(uiGid, OSS_MONEY_MODULE_35, stPlayerBaseInfo._iGold, CONST_WISH_PAY_GOLD50);
            CHECK_RETURN(iRet);
        }
        break;
    default:
        return ERROR_WISH_TYPE;
    }

    //设置许愿完成
    stWishData._astWishList[iReqType-1] = 0;

    //根据奖励倍数发放金钱
    int iDropGold = 0;
    switch(iReqType)
    {
    case ECONST_WISH_REQ_SILVER  :  //银币许愿
        {
            iRet = stPlayerBaseInfo.AddSilver(stPlayerBaseInfo._i64Silver, iRatioTimes*CONST_WISH_PAY_SILVER);
            CHECK_RETURN(iRet);
        }
        break;
    case ECONST_WISH_REQ_GOLD1   :  //10金币许愿
        {
            iDropGold = iRatioTimes*CONST_WISH_PAY_GOLD10;
            iRet = stPlayerBaseInfo.AddGold(stPlayerBaseInfo._iGold, iDropGold);
            CHECK_RETURN(iRet);
        }
        break;
    case ECONST_WISH_REQ_GOLD2   :  //50金币许愿
        {
            iDropGold = iRatioTimes*CONST_WISH_PAY_GOLD50;
            iRet = stPlayerBaseInfo.AddGold(stPlayerBaseInfo._iGold, iDropGold);
            CHECK_RETURN(iRet);
        }
    default:
        break;
    }

    if (iDropGold > 0)
    {
        CMainCtrl::m_pstMain->m_stOssMgr.TriggerMoney(uiGid, OSS_MONEY_ADD_GOLD, OSS_MODULE_WISH, iDropGold);
    }

    m_bUpdateMoneyData = true; 

    stAns.set_many_times(iRatioTimes);

    this->UpdateData(uiGid);

    return iRet;
}

//检查是否许愿过,没有的就初始化
bool CWishMgr::CheckValidWish(int iReqType, CWishData& stWishData)
{
    bool bRes = false;

    if( stWishData._astWishList.Size()==0 )
    {
        this->InitWish(stWishData);

        //需要更新
        this->m_bUpdateWishData = true;
    }

    for(int i=0; i<stWishData._astWishList.Size(); ++i)
    {
        //数据记录从0开始
        if( i==iReqType-1 && stWishData._astWishList[i]>0 )
        {
            return true; 
        }
    }

    return bRes;
}

//初始化许愿池信息
int CWishMgr::InitWish(CWishData& stWishData)
{
    stWishData._astWishList.m_iUsedCount = CONST_WISH_NUM;

    for(int i=0; i<stWishData._astWishList.Size(); ++i)
    {
        stWishData._astWishList[i] = 1;
    }

    return 0;
}

void CWishMgr::UpdateData(unsigned int uiGid)
{
    //保存数据
    if( m_bUpdateWishData )
    {
        //个人详细数据
        int iIndex = CMainCtrl::m_pstMain->m_stPlayerDetailInfoHash.HashFind(uiGid);
        CPlayerDetailInfo& stPlayerDetailInfo = CMainCtrl::m_pstMain->m_stPlayerDetailInfoHash[iIndex];

        CVarObjectKey stKey;
        stKey.m_chDataType = DT_PLAYER_DETAIL_INFO;
        stKey.m_u64ID = uiGid;
        CMainCtrl::m_pstMain->UpdateData(stKey, stPlayerDetailInfo, VOP_UPDATE);

        m_bUpdateWishData = false;
    }

    if( m_bUpdateMoneyData )
    {
        //在cmdact里面已经做了用户数据存在的检查，这里直接用
        int iIndex = CMainCtrl::m_pstMain->m_stPlayerBaseInfoHash.HashFind(uiGid);
        CPlayerBaseInfo& stPlayerBaseInfo = CMainCtrl::m_pstMain->m_stPlayerBaseInfoHash[iIndex];

        CVarObjectKey stKey;
        stKey.m_chDataType = DT_PLAYER_BASE_INFO;
        stKey.m_u64ID = stPlayerBaseInfo._uiGID;
        CMainCtrl::m_pstMain->UpdateData(stKey, stPlayerBaseInfo, VOP_UPDATE);

        //推送money
        CMainCtrl::m_pstMain->m_stNotifyMgr.Notify(uiGid, NOTIFY_USER_MONEY);

        m_bUpdateMoneyData = false;
    }
}

//获取活动信息
int CWishMgr::GetWishInfo(unsigned int uiGid, MsgAnsWish & stAns)
{
    int iRet = 0;

    //个人详细数据
    int iIndex = CMainCtrl::m_pstMain->m_stPlayerDetailInfoHash.HashFind(uiGid);
    CPlayerDetailInfo& stPlayerDetailInfo = CMainCtrl::m_pstMain->m_stPlayerDetailInfoHash[iIndex];
    CWishData& stWishData = stPlayerDetailInfo._stWishData;

    if( stWishData._astWishList.Size()==0 )
    {
        this->InitWish(stWishData);

        //需要更新
        this->m_bUpdateWishData = true;

        this->UpdateData(uiGid);
    }

    for(int i=0; i<stWishData._astWishList.Size(); ++i)
    {
        MsgWishItem* pWishOne = stAns.add_wish_infos();

        pWishOne->set_wish_item(i+1);
        pWishOne->set_wish_value(stWishData._astWishList[i]);
    }

    return iRet;
}

int CWishMgr::LoadConfig(const char* szCfgPath)
{
    int iRet = 0;

    if (szCfgPath == NULL)
    {
        CT_ERROR(("wish Cfg Path is null"));
        return RET_SYSTEM_FAIL;
    }

    pb_cfg_act stWishCfg;
    std::fstream stFileInput(szCfgPath, std::ios::in | std::ios::binary);
    if (!stWishCfg.ParseFromIstream(&stFileInput))
    {
        CT_ERROR(("Failed to Parse wish config!"));
        return RET_SYSTEM_FAIL;
    }

    //解析许愿池配置信息
    CT_TRACE(("wish config count %d", stWishCfg.wish_rows_size()));
    for (int i = 0; i < stWishCfg.wish_rows_size(); ++i)
    {
        const pb_cfg_act_pb_cfg_wish_unit& stPBUnit = stWishCfg.wish_rows(i);

        CWishConfigData stDataConfig;

        stDataConfig.iWishType       = stPBUnit.wish_type();
        stDataConfig.iStartTimes     = stPBUnit.start_times();
        stDataConfig.iEndTimes       = stPBUnit.end_times();
        stDataConfig.iRatio          = stPBUnit.ratio();

        stDataConfig._bHasConfig = true;
        iRet = _stWishCfg.AddWishConfig(stDataConfig);
        CT_RETURN(iRet);
    }

    return 0;
}

